/*
 * =========================================================================
 *  Program Name:  sg.gov.cpf.css.caf.core.util.FileUtil
 *
 *  Copyright (C)2009 NCS Pte. Ltd. All Rights Reserved
 *
 *  Change Revision
 * -------------------------------------------------------------------------
 *  Date         Remarks
 *  08 Feb 2009  - Initial Release
 *  
 * =========================================================================
 */
package canglang.scan.core.base.util;

import java.io.*;
import java.util.Date;
import java.util.Random;
import java.math.BigInteger;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

/**
 * This class is used to handle File IO processing.
 *
 * @author cpfci
 */
public class FileUtil extends FileUtils {
    /**
     * Automatically generated variable: ONE_K_BYTES
     */
    private static final int ONE_K_BYTES = 1024;
    private static final Logger log = Logger.getLogger(FileUtil.class);

    public static void getFielContentAsBytes(String file, OutputStream os) throws Exception {
        File srcFile = new File(file);
        InputStream inPut = new FileInputStream(srcFile);
        try {
            byte[] bytes = new byte[ONE_K_BYTES];
            int i;
            while ((i = inPut.read(bytes)) != -1) {
                os.write(bytes, 0, i);
            }
        } catch (IOException ie) {
            log.error("error in getFielContentAsBytes", ie);
        } finally {
            inPut.close();
        }
    }

    /**
     * This method is to copy file
     *
     * @param String srcPath, must including the source file path and name.
     * @param String destPath, must including the destination file path and name.
     * @throws Exception
     */
    public static void copyFile(String srcPath, String destPath) throws Exception {
        FileInputStream inPut = null;
        FileOutputStream outPut = null;
        try {

            inPut = new FileInputStream(srcPath);
            outPut = new FileOutputStream(destPath);
            byte[] bytes = new byte[ONE_K_BYTES];
            int i;
            while ((i = inPut.read(bytes)) != -1) {
                outPut.write(bytes, 0, i);
            }
        } catch (Exception e) {
            log.error("", e);
            throw e;
        } finally {
            if (inPut != null) inPut.close();
            if (outPut != null) outPut.close();
        }
    }
    
    /**
     * This method is to copy file
     *
     * @param String srcPath, must including the source file path and name.
     * @param String destPath, must including the destination file path and name.
     * @throws Exception
     */
    public static void copyFile(File srcfile, String destPath) throws Exception {
        FileInputStream inPut = null;
        FileOutputStream outPut = null;
        try {

            inPut = new FileInputStream(srcfile);
            outPut = new FileOutputStream(destPath);
            byte[] bytes = new byte[ONE_K_BYTES];
            int i;
            while ((i = inPut.read(bytes)) != -1) {
                outPut.write(bytes, 0, i);
            }
        } catch (Exception e) {
            log.error("", e);
            throw e;
        } finally {
            if (inPut != null) inPut.close();
            if (outPut != null) outPut.close();
        }
    }    

    
    /**
     * This method is to delete file
     *
     * @param String srcPath, must including the source file path and name.
     * @throws Exception
     */
    public static void deleteFile(String srcPath) throws Exception {
        try {
            File inPut = new File(srcPath);
            inPut.delete();
        } catch (Exception e) {
            log.error("", e);
            throw e;
        }
    }

    public static String getFullFileName(String filePath, String fileName) {
        filePath = filePath.replaceAll("\\\\", "/");
        if (!filePath.endsWith("/"))
            filePath = filePath + "/";
        return filePath + fileName;
    }

    /**
     * This method is to move file from one folder to the other
     *
     * @param String srcPath, must including the source file path and name.
     * @param String destPath, must including the destination file path and name.
     * @throws Exception
     */
    public static void moveFile(String srcPath, String destPath) throws Exception {
        copyFile(srcPath, destPath);
        deleteFile(srcPath);
    }

    /**
     * This method is to get the file size, represent as bytes.
     *
     * @param String srcPath
     * @return long length of the file
     * @throws Exception
     */
    public static long getFileSize(String srcPath) throws Exception {
        try {
            File inputFile = new File(srcPath);
            return inputFile.length();
        } catch (Exception e) {
            log.error("", e);
            throw e;
        }
    }

    /**
     * This method is to get the last modified date of the file
     *
     * @param String srcPath
     * @return Date the last modified date of the file
     * @throws Exception
     */
    public static Date getFileLastModifiedTime(String srcPath) throws Exception {
        try {
            File inputFile = new File(srcPath);
            return new Date(inputFile.lastModified());
        } catch (Exception e) {
            log.error("", e);
            throw e;
        }
    }

    public static boolean existFile(String fullFileName) {
        File f = new File(fullFileName);
        return f.exists();
    }

    public static byte[] convertToByte(File file) {
        if(file==null)return null;
        BufferedInputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            in = new BufferedInputStream(new FileInputStream(file));
            out = new ByteArrayOutputStream(1024);
            byte[] temp = new byte[1024];
            int size;
            while ((size = in.read(temp)) != -1) {
                out.write(temp, 0, size);
            }
            return out.toByteArray();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } finally {
            try {
                if (in != null) in.close();
                if (out != null) out.close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }
    
    /**
     * Create temp file for each attachment
     *
     * @param b Attachment in byte array format
     * @throws IOException Exception throws when creating the temp file
     */
    public static void createFile(byte[] b, File file) throws IOException {
        FileOutputStream ous = new FileOutputStream(file);
        ous.write(b);
        ous.close();
    }

    public static final File TEMP_DIRECTORY_ROOT = new File(System.getProperty("java.io.tmpdir") + File.separator);

	private static final String TEMP_FILE_PREIFX = "APP";


	/**
	 * @param aLength Length of key array.
	 * @return A byte array, filled with random value.
	 */
	public static byte[] generateKey(int aLength) {
		byte[] key = new byte[aLength];
		Random rand = new Random(System.currentTimeMillis());
		rand.nextBytes(key);

		BigInteger keyval = new BigInteger(key);
//		System.out.println("Encryption Key: " + keyval.toString(16));

		return key;
	}

	/**
	 * This method returns the path for the temporary file.
	 * @return The path of the temporary file
	 * @throws IOException
	 */
	public static String getTempFilePath() throws IOException {
		return getTempFilePath(null);
	}

	/**
	 * This method returns the path for the temporary file.
	 *
	 * @param suffix
	 *            A dot + file extension
	 * @return The path of the temporary file
	 * @throws IOException
	 */
	public static String getTempFilePath(String suffix) throws IOException {
		System.out.println(System.getProperty("java.io.tmpdir")
				+ File.separator);
		File tempfile = File.createTempFile(TEMP_FILE_PREIFX, suffix,
				TEMP_DIRECTORY_ROOT);
		tempfile.deleteOnExit();
//		System.out.println("File Path (Before Encryption): " + tempfile.getAbsolutePath());
		String absolutePath = "";
		try {
			absolutePath = tempfile.getAbsolutePath();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Exception is thrown during encryption");
		}
//		System.out.println("File Path (AFter Encryption): " + absolutePath);
		return absolutePath;
	}

	/**
	 * This method retrieves the outputstream for the temporary file
	 * @param aPath The file path of the temporary file
	 * @return The output stream of the temporary file
	 * @throws IOException
	 */
	public static BufferedOutputStream getTempOutputStream(String aPath) throws IOException {
		String decryptedPath = "";
		try {
			decryptedPath = aPath;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Exception is thrown during decryption");
		}
//		System.out.println("getTempOutputStream:: File Path (AFter Decryption): " + decryptedPath);
		BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(decryptedPath));
		return out;
	}

	/**
	 * This method retrieves the inputstream of the temporary file
	 * @param aPath The path of the temporary file
	 * @return The input stream of the temporary file
	 * @throws FileNotFoundException
	 */
	public static BufferedInputStream getTempInputStream(String aPath) throws FileNotFoundException {
		String decryptedPath = "";
		try {
			decryptedPath = aPath;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Exception is thrown during decryption");
		}
//		System.out.println("getTempInputStream:: File Path (AFter Decryption): " + decryptedPath);
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(decryptedPath));
		return in;
	}

	/**
	 * This method is to remove the temporary file in the memory
	 * @param aPath The file path of the temporary file
	 */
	public static void disposeTempFile(String aPath) {
		String decryptedPath = "";
		try {
			decryptedPath = aPath;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Exception is thrown during decryption");
		}
//		System.out.println("disposeTempFile:: File Path (AFter Decryption): " + decryptedPath);
		File tempFile = new File(decryptedPath);
		tempFile.delete();
	}


	/**
	 * This is a simply utility to copy the inputstream data to the outputstream
	 * @param in The inputstream of the data
	 * @param out The ouptputstream for the data to be copied
	 * @throws IOException
	 */
	public  static void copy(InputStream in , OutputStream out ) throws IOException {

        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();
    }
}
